{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    },
    "accelerator": "TPU"
  },
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "GHQVd93i4pDm",
        "outputId": "1e22ed8a-fbee-4b28-ff20-d01ef9f75381"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Collecting cantera\n",
            "  Downloading Cantera-3.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.9 MB)\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m5.9/5.9 MB\u001b[0m \u001b[31m11.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25hRequirement already satisfied: numpy>=1.12.0 in /usr/local/lib/python3.10/dist-packages (from cantera) (1.23.5)\n",
            "Collecting ruamel.yaml>=0.15.34 (from cantera)\n",
            "  Downloading ruamel.yaml-0.18.5-py3-none-any.whl (116 kB)\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m116.4/116.4 kB\u001b[0m \u001b[31m11.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25hRequirement already satisfied: packaging in /usr/local/lib/python3.10/dist-packages (from cantera) (23.2)\n",
            "Collecting ruamel.yaml.clib>=0.2.7 (from ruamel.yaml>=0.15.34->cantera)\n",
            "  Downloading ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (526 kB)\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m526.7/526.7 kB\u001b[0m \u001b[31m9.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25hInstalling collected packages: ruamel.yaml.clib, ruamel.yaml, cantera\n",
            "Successfully installed cantera-3.0.0 ruamel.yaml-0.18.5 ruamel.yaml.clib-0.2.8\n"
          ]
        }
      ],
      "source": [
        "!pip install cantera\n"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "pip install --upgrade cantera\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "NEILzHT9DgJt",
        "outputId": "91e205f0-4707-40f8-876d-e5a7b030f0ea"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Requirement already satisfied: cantera in /usr/local/lib/python3.10/dist-packages (3.0.0)\n",
            "Requirement already satisfied: numpy>=1.12.0 in /usr/local/lib/python3.10/dist-packages (from cantera) (1.23.5)\n",
            "Requirement already satisfied: ruamel.yaml>=0.15.34 in /usr/local/lib/python3.10/dist-packages (from cantera) (0.18.5)\n",
            "Requirement already satisfied: packaging in /usr/local/lib/python3.10/dist-packages (from cantera) (23.2)\n",
            "Requirement already satisfied: ruamel.yaml.clib>=0.2.7 in /usr/local/lib/python3.10/dist-packages (from ruamel.yaml>=0.15.34->cantera) (0.2.8)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "import cantera as ct\n",
        "import matplotlib.pyplot as plt\n",
        "\n",
        "import subprocess\n",
        "\n",
        "# Replace 'gri30.cti' with the name of your Chemkin mechanism file\n",
        "mechanism_file = 'gri30.cti'\n",
        "yaml_file = 'gri30.yaml'\n",
        "\n",
        "result = subprocess.run(['cti2yaml', mechanism_file, '-o', yaml_file], check=False, capture_output=True)\n",
        "\n",
        "if result.returncode != 0:\n",
        "    print(f\"Error: {result.stderr.decode()}\")\n",
        "\n",
        "\n",
        "# Convert Chemkin mechanism to YAML format\n",
        "\n",
        "yaml_file = ct.convert_chemical_file('gri30.cti', fmt='yaml', outName='gri30.yaml')\n",
        "\n",
        "# Create a Cantera Solution object\n",
        "\n",
        "gas = ct.Solution.from_yaml(yaml_file)\n",
        "\n",
        "# Define the mechanism and initial state\n",
        "\n",
        "mechanism=ct.mechanism('gri30.cti')\n",
        "\n",
        "# Define the state for contstant-volume combustion\n",
        "\n",
        "T = 800 # Initial Temperature (K)\n",
        "P = 1000000 # Initial Pressure (Pa)\n",
        "\n",
        "# Define the fuel and oxidizer compositions\n",
        "\n",
        "fuel = 'n-heptane'\n",
        "oxidizer = 'O2:N2:H2O=4:1.5:0.3'\n",
        "\n",
        "# Set the initial state and create the reactor object\n",
        "\n",
        "state = ct.State(mechanism, T, P)\n",
        "state.TPX = {fuel:1.0,oxidizer:1.0}\n",
        "\n",
        "# Define the reactor object\n",
        "\n",
        "r = ct.State(mechanism, T, P)\n",
        "\n",
        "# Set hydrogen energy share (HES) values\n",
        "\n",
        "hes_values = [0, 1, 5, 10, 25, 50]\n",
        "\n",
        "# Define engien load values\n",
        "\n",
        "load_values = [0.25, 0.5, 0.75, 1.0]\n",
        "\n",
        "# Initialize data storage arrays\n",
        "\n",
        "power_data = []\n",
        "hrr_data = []\n",
        "efficiency_data = []\n",
        "CO_emissions_data = []\n",
        "\n",
        "# Loop through HES values\n",
        "\n",
        "for hes in hes_values:\n",
        "  # Modify fuel composition based on HES\n",
        "  fuel_mol = ct.Quantity(fuel,1.0-hes/100)\n",
        "  hydrogen_mol = ct.Quantity('H2',hes/100)\n",
        "  fuel_mixture = {fuel_mol:1.0,hydrogen_mol:1.0}\n",
        "\n",
        "  # Update reactor state with modified fuel composition\n",
        "\n",
        "  state.TPX = fuel_mixture\n",
        "\n",
        "  # Loop through engine load values\n",
        "\n",
        "  for load in load_values:\n",
        "    # Set the equivalence ratio\n",
        "    equivalence_ratio = load/0.75\n",
        "    # Perform constant volume combustion simulation\n",
        "    r.run(equivalence_ratio)\n",
        "    # Calculate engine power\n",
        "    power = r.work()\n",
        "    # Calculate heat release rate\n",
        "    hrr = r.thermo.heat_release_rate()\n",
        "    # Calculate brake thermal efficiency\n",
        "    efficiency = power/(r.thermo.enthalpy_inlet()-r.thermo.enthalpy_outlet)\n",
        "    # Calculate CO emmisions\n",
        "    CO_emissions = r.thermo.mole_fractions('CO')\n",
        "    # Store results in data arrays\n",
        "    power_data.append([hes, load, power])\n",
        "    hrr_data.append([hes, load, efficiency])\n",
        "    CO_emissions_data.append([hes, load, CO_emissions])\n",
        "\n",
        "    # Process and plot the results\n",
        "\n",
        "for data_type, data_array in zip(['power', 'hrr', 'efficiency', 'CO_emissions'], [power_data, hrr_data, efficiency_data, CO_emissions_data]):\n",
        "    # Process data into 2D arrays for each load\n",
        "    processed_data = []\n",
        "    for load in load_values:\n",
        "        filtered_data = [data[1:] for data in data_array if data[0] == hes and data[1] == load]\n",
        "        processed_data.append(filtered_data[0])\n",
        "\n",
        "# Create subplots\n",
        "fig, ax = plt.subplots()\n",
        "\n",
        "# Plot data for each load\n",
        "for load_index, load_data in enumerate(processed_data):\n",
        "    load_label = 'Load:' + str(load_values[load_index] * 100) + '%'\n",
        "    ax.plot(hes_values, [data[2] for data in load_data], label=load_label)\n",
        "\n",
        "# Set plot labels and title\n",
        "ax.set_xlabel('Hydrogen Energy Share (%)')\n",
        "ax.set_ylabel(data_type)\n",
        "ax.set_title('Effect of Hydrogen Share ' + data_type)\n",
        "ax.legend()\n",
        "\n",
        "# Show plot\n",
        "plt.show()\n",
        "\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 297
        },
        "id": "E3XHR-SO4zUm",
        "outputId": "c92046a6-8abb-45e2-f3d4-eac67fa9c1ad"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Error: usage: cti2yaml [-h] [--input-encoding] [--quiet] [--no-validate] input [output]\n",
            "cti2yaml: error: unrecognized arguments: -o gri30.yaml\n",
            "\n"
          ]
        },
        {
          "output_type": "error",
          "ename": "AttributeError",
          "evalue": "ignored",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-12-62f5f7927209>\u001b[0m in \u001b[0;36m<cell line: 18>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     16\u001b[0m \u001b[0;31m# Convert Chemkin mechanism to YAML format\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     17\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 18\u001b[0;31m \u001b[0myaml_file\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mct\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconvert_chemical_file\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'gri30.cti'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfmt\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'yaml'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moutName\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'gri30.yaml'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     19\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     20\u001b[0m \u001b[0;31m# Create a Cantera Solution object\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;31mAttributeError\u001b[0m: module 'cantera' has no attribute 'convert_chemical_file'"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "import cantera as ct\n",
        "import matplotlib.pyplot as plt\n",
        "import subprocess\n",
        "\n",
        "# Replace 'gri30.cti' with the name of your Chemkin mechanism file\n",
        "mechanism_file = 'gri30.cti'\n",
        "yaml_file = 'gri30.yaml'\n",
        "\n",
        "# Run the cti2yaml command using subprocess\n",
        "subprocess.run(['cti2yaml', mechanism_file, '-o', yaml_file], check=True)\n",
        "\n",
        "# Create a Cantera Solution object\n",
        "gas = ct.Solution.from_yaml(yaml_file)\n",
        "\n",
        "# Define the state for constant-volume combustion\n",
        "T = 800  # Initial Temperature (K)\n",
        "P = 1000000  # Initial Pressure (Pa)\n",
        "\n",
        "# Define the fuel and oxidizer compositions\n",
        "fuel = 'n-heptane'\n",
        "oxidizer = 'O2:N2:H2O=4:1.5:0.3'\n",
        "\n",
        "# Set the initial state and create the reactor object\n",
        "state = ct.State(gas, T, P)\n",
        "state.TPX = {fuel: 1.0, oxidizer: 1.0}\n",
        "\n",
        "# Define engine load values\n",
        "load_values = [0.25, 0.5, 0.75, 1.0]\n",
        "\n",
        "# Initialize data storage arrays\n",
        "power_data = []\n",
        "hrr_data = []\n",
        "efficiency_data = []\n",
        "CO_emissions_data = []\n",
        "\n",
        "# Loop through engine load values\n",
        "for load in load_values:\n",
        "    # Set the equivalence ratio\n",
        "    equivalence_ratio = load / 0.75\n",
        "    # Perform constant volume combustion simulation\n",
        "    gas.TPX = T, P, {fuel: 1.0, oxidizer: equivalence_ratio}\n",
        "    r = ct.IdealGasConstPressureReactor(gas)\n",
        "    sim = ct.ReactorNet([r])\n",
        "    sim.advance_to_steady_state()\n",
        "    # Calculate engine power\n",
        "    power = r.thermo.work()\n",
        "    # Calculate heat release rate\n",
        "    hrr = r.thermo.heat_release_rate()\n",
        "    # Calculate brake thermal efficiency\n",
        "    efficiency = power / (r.thermo.enthalpy_mass - gas.h())\n",
        "    # Calculate CO emissions\n",
        "    CO_emissions = r.thermo['CO'].Y[0]\n",
        "    # Store results in data arrays\n",
        "    power_data.append([load, power])\n",
        "    hrr_data.append([load, hrr])\n",
        "    efficiency_data.append([load, efficiency])\n",
        "    CO_emissions_data.append([load, CO_emissions])\n",
        "\n",
        "# Process and plot the results\n",
        "fig, axs = plt.subplots(2, 2, figsize=(12, 8))\n",
        "axs = axs.flatten()\n",
        "data_types = ['Power', 'Heat Release Rate', 'Efficiency', 'CO Emissions']\n",
        "\n",
        "for i, (data_type, data_array) in enumerate(zip(data_types, [power_data, hrr_data, efficiency_data, CO_emissions_data])):\n",
        "    axs[i].plot([data[0] for data in data_array], [data[1] for data in data_array], marker='o')\n",
        "    axs[i].set_xlabel('Engine Load')\n",
        "    axs[i].set_ylabel(data_type)\n",
        "    axs[i].set_title(f'{data_type} vs. Engine Load')\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 366
        },
        "id": "OYFnSMUOMr4N",
        "outputId": "943b23dc-10d1-4ddc-8a4a-d4fb7a6bda02"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "error",
          "ename": "CalledProcessError",
          "evalue": "ignored",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mCalledProcessError\u001b[0m                        Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-19-97f1bff9ca23>\u001b[0m in \u001b[0;36m<cell line: 10>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      8\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      9\u001b[0m \u001b[0;31m# Run the cti2yaml command using subprocess\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 10\u001b[0;31m \u001b[0msubprocess\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'cti2yaml'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmechanism_file\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'-o'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0myaml_file\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcheck\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     11\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     12\u001b[0m \u001b[0;31m# Create a Cantera Solution object\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/lib/python3.10/subprocess.py\u001b[0m in \u001b[0;36mrun\u001b[0;34m(input, capture_output, timeout, check, *popenargs, **kwargs)\u001b[0m\n\u001b[1;32m    524\u001b[0m         \u001b[0mretcode\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mprocess\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpoll\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    525\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mcheck\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mretcode\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 526\u001b[0;31m             raise CalledProcessError(retcode, process.args,\n\u001b[0m\u001b[1;32m    527\u001b[0m                                      output=stdout, stderr=stderr)\n\u001b[1;32m    528\u001b[0m     \u001b[0;32mreturn\u001b[0m \u001b[0mCompletedProcess\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mprocess\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mretcode\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstdout\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstderr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;31mCalledProcessError\u001b[0m: Command '['cti2yaml', 'gri30.cti', '-o', 'gri30.yaml']' returned non-zero exit status 2."
          ]
        }
      ]
    }
  ]
}